﻿using System;
using System.Web;
using System.Xml;
using System.Text;
using System.IO;

namespace VioletDevelopmentLaboratory.Net.Web.Component
{
	public class TrackbackHandler : System.Web.IHttpHandler
	{
		public Boolean IsReusable { get { return false; } }

		public void ProcessRequest(HttpContext context)
		{
			if (context == null)
				throw new ArgumentNullException("context");

			String rawUrl = HttpContext.Current.Request.RawUrl.ToLower();
			String[] rawUrlParam = rawUrl.Substring(rawUrl.LastIndexOf("vwebtrackback.ashx")).Split(new Char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

			if (rawUrlParam == null || rawUrlParam.Length != 3)
			{
				this.writeXml(context, "1", "Invalid Trackback Url.");
				return;
			}

			String componentID = rawUrlParam[1].Trim();
			String relationID = rawUrlParam[2].Trim();

			if (String.IsNullOrEmpty(componentID) || String.IsNullOrEmpty(relationID) || !VUtility.IsGuid(relationID))
			{
				this.writeXml(context, "1", "Invalid Parameter.");
				return;
			}

			String url = "", blogName = "", title = "", excerpt = "";

			String parametersString = "";
			using (StreamReader streamReader = new StreamReader(context.Request.InputStream))
			{
				parametersString = streamReader.ReadToEnd();
			}

			if (!String.IsNullOrEmpty(parametersString))
			{
				String[] parameters = parametersString.Split(new Char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
				foreach (String paramter in parameters)
				{
					if (paramter.ToLower().IndexOf("url=") > -1)
						url = this.urlDecode(paramter.Substring("url=".Length));
					else if (paramter.ToLower().IndexOf("blog_name=") > -1)
						blogName = this.urlDecode(paramter.Substring("blog_name=".Length));
					else if (paramter.ToLower().IndexOf("title=") > -1)
						title = this.urlDecode(paramter.Substring("title=".Length));
					else if (paramter.ToLower().IndexOf("excerpt=") > -1)
						excerpt = VUtility.RemoveHtmlTag(this.urlDecode(paramter.Substring("excerpt=".Length)));
				}
			}

			if (String.IsNullOrEmpty(componentID) || String.IsNullOrEmpty(relationID) || !VUtility.IsGuid(relationID) || String.IsNullOrEmpty(url) ||
				url.Length > 300 || String.IsNullOrEmpty(blogName) || String.IsNullOrEmpty(title) || String.IsNullOrEmpty(excerpt))
			{
				this.writeXml(context, "1", "Invalid Parameter.");
				return;
			}

			try
			{
				blogName = blogName.Length > 50 ? blogName.Substring(0, 50) : blogName;
				title = title.Length > 100 ? title.Substring(0, 100) : title;
				excerpt = excerpt.Length > 300 ? excerpt.Substring(0, 300) : excerpt;

				switch (Trackback.Add(componentID, relationID, url, blogName, title, excerpt))
				{
					case TrackbackAddResult.Success:
						this.writeXml(context, "0", String.Empty);
						break;
					case TrackbackAddResult.Exists:
						this.writeXml(context, "1", "Exists Url.");
						break;
					case TrackbackAddResult.Failure:
						this.writeXml(context, "1", "Unknown Error.(1)");
						break;
				}
			}
			catch
			{
				this.writeXml(context, "1", "Unknown Error.(2)");
			}
		}

		private void writeXml(HttpContext context, String error, String message)
		{
			String xml = String.Format("<?xml version=\"1.0\" encoding=\"utf-8\" ?><response><error>{0}</error><message>{1}</message></response>", error, message); ;

			context.Response.ContentEncoding = System.Text.Encoding.UTF8;
			context.Response.ContentType = "text/xml";
			context.Response.Write(xml);
		}

		private String urlDecode(String source)
		{
			source = source.Replace("%20", "+");

			String euckrDecode = HttpUtility.UrlDecode(source, Encoding.GetEncoding(949));
			String euckrEncode = HttpUtility.UrlEncode(euckrDecode, Encoding.GetEncoding(949));

			if (source.ToLower() == euckrEncode.ToLower())
				return euckrDecode;
			else
				return HttpUtility.UrlDecode(source, Encoding.UTF8);
		}
	}
}
